﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Linq;

using ECCIT;
using ECCIT.Data;
using ECCIT.Business.DAL;

using OgilvyOne.UKNow.Common;
using OgilvyOne.UKNow.Globalization;
using OgilvyOne.UKNow.Utility;
using OgilvyOne.UKNow.Model;
using OgilvyOne.UKNow.IDAL;

namespace OgilvyOne.UKNow.DAL
{
    public class EventsLogDAL : UKNowBaseDAL, IDALEventsLog
    {
        private const string TBL_NAME               = "UKNOW_EVENTS_LOG";

        private const string COL_LANG_ID            = "COL_LANG_ID";
        private const string COL_LOG_ID             = "COL_LOG_ID";
        private const string COL_EVENTS_ID           = "COL_EVENTS_ID";
        private const string COL_LOG_INSERT_TIME           = "COL_LOG_INSERT_TIME";
        private const string COL_LOG_UPDATE_TIME         = "COL_LOG_UPDATE_TIME";

        public override string TableName { get { return TBL_NAME; } }

        public override Type ModelType { get { return typeof(EventsLogModel); } }

        [PrimaryKey]
        public IField LanguageID { get { return FieldFactory.Create(ModelType, "LanguageID", ColumnFactory.CreateColumn(COL_LANG_ID, DataType.Int)); } }
        [PrimaryKey]
        public IField ID { get { return FieldFactory.Create(ModelType, "ID", ColumnFactory.CreateColumn(COL_LOG_ID, DataType.Int)); } }
        public IField EventsID { get { return FieldFactory.Create(ModelType, "EventsID", ColumnFactory.CreateColumn(COL_EVENTS_ID, DataType.Int)); } }
        public IField InsertedTime { get { return FieldFactory.Create(ModelType, "InsertedTime", ColumnFactory.CreateColumn(COL_LOG_INSERT_TIME, DataType.DateTime)); } }
        public IField UpdatedTime { get { return FieldFactory.Create(ModelType, "UpdatedTime", ColumnFactory.CreateColumn(COL_LOG_UPDATE_TIME, DataType.DateTime)); } }

        public override IField[] InsertFields { get { return new IField[] { LanguageID, EventsID, InsertedTime, UpdatedTime }; } }
        public override IField[] SelectFields { get { return new IField[] { LanguageID, ID, EventsID, InsertedTime, UpdatedTime }; } }
        public override IField[] UpdateFields { get { return InsertFields; } }

        public EventsLogDAL() { }

        public EventsLogDAL(LanguageType languageType) { this.Language = LanguageFactory.Create(languageType); }

        
        #region IDALWarmup Members

        public EventsLogModel GetModelByID(int? id)
        {
            EventsLogModel model = (EventsLogModel)GetModelByPrimaryKey(this.GetType(), new KeyValuePair<IField, object>[] { new KeyValuePair<IField, object>(LanguageID, (int)this.Language.LanguageType), new KeyValuePair<IField, object>(this.ID, id) });
            return model;
        }

        public IList<int?> GetEventsIDsOrderByLogCount()
        {
            string cmd = string.Format("SELECT DISTINCT {0}, COUNT({1}) AS {2} FROM {3} WHERE {4}={5} GROUP BY {0} ORDER BY {2} DESC", 
                COL_EVENTS_ID, COL_LOG_ID, "LOGCOUNT", TBL_NAME, COL_LANG_ID, (int)this.Language.LanguageType);

            IList<int?> ids = new List<int?>();
            using (IDataReader reader = DBHelper.ExecuteReader(cmd))
            {
                while (reader.Read())
                    ids.Add((int?)reader[COL_EVENTS_ID]);
            }
            return ids;
        }

        public ResultInfo Save(EventsLogModel modelInfo)
        {
            if (modelInfo == null) throw new ArgumentNullException("modelInfo");

            ResultInfo result = new ResultInfo(false);

            try
            {
                int rowsAffected = 0;
                if (modelInfo.ID == null)   // insert
                    rowsAffected = Insert(modelInfo, null);
                else // update
                    rowsAffected = UpdateByPrimaryKey(modelInfo, null);

                if (rowsAffected > 0)
                {
                    result.Message = Language.GetAlertMessage(ModelType, Enums.Action.Save, Enums.ActionResult.Success);
                    result.Result = true;
                    result.ReturnObject = modelInfo;
                }
            }
            catch (Exception ex)
            {
                result.Exception = ex;
                result.Message = Language.GetAlertMessage(ModelType, Enums.Action.Save, Enums.ActionResult.Exception, ex);
            }

            return result;
        }

        public ResultInfo Delete(IList<int?> idList)
        {
            ResultInfo result = new ResultInfo(false);
            using (IDbConnection conn = DBHelper.GetDbConnection())
            {
                conn.Open();
                IDbTransaction trans = conn.BeginTransaction();
                try
                {
                    foreach (int? id in idList)
                        DeleteModelByPrimaryKey(trans, this.GetType(), new KeyValuePair<IField, object>[] { new KeyValuePair<IField, object>(LanguageID, (int)this.Language.LanguageType), new KeyValuePair<IField, object>(this.ID, id) });

                    trans.Commit();
                    result.Result = true;
                    result.Message = Language.GetAlertMessage(ModelType, Enums.Action.Delete, Enums.ActionResult.Success);
                }
                catch (Exception ex)
                {
                    trans.Rollback();
                    result.Message = Language.GetAlertMessage(ModelType, Enums.Action.Delete, Enums.ActionResult.Exception, ex);
                }
                finally
                {
                    trans.Dispose();
                }
            }

            return result;
        }

        public ResultInfo DeleteByEventsID(IDbTransaction trans, int? eventsID)
        {
            ResultInfo result = new ResultInfo(false);
            try
            {
                string whereClause = string.Format("where {0}={1} and {2}={3}", COL_LANG_ID, (int)this.Language.LanguageType, COL_EVENTS_ID, eventsID);
                Delete(trans, whereClause);
                result.Result = true;
                result.Message = Language.GetAlertMessage(ModelType, Enums.Action.Delete, Enums.ActionResult.Success);
            }
            catch (Exception ex)
            {
                result.Exception = ex;
                result.Message = Language.GetAlertMessage(ModelType, Enums.Action.Delete, Enums.ActionResult.Exception, ex);
            }

            return result;
        }

        #endregion
    }
}
